/*
 *
 *  * | Licensed 未经许可不能去掉「OPENIITA」相关版权
 *  * +----------------------------------------------------------------------
 *  * | Author: xw2sy@163.com
 *  * +----------------------------------------------------------------------
 *
 *  Copyright [2024] [OPENIITA]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * /
 */

package cc.iotkit.data.service;

import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.satoken.utils.LoginHelper;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.data.dao.BizWorkorderFailureRepository;
import cc.iotkit.data.dao.BizWorkorderRepository;
import cc.iotkit.data.dao.IJPACommData;
import cc.iotkit.data.manager.IBizWorkorder;
import cc.iotkit.data.manager.IBizWorkorderFailure;
import cc.iotkit.data.model.QTbSysDictData;
import cc.iotkit.data.model.QTbSysUser;
import cc.iotkit.data.model.TbBizWorkorder;
import cc.iotkit.data.model.TbBizWorkorderFailure;
import cc.iotkit.data.util.PredicateBuilder;
import cc.iotkit.model.biz.BizWorkorder;
import cc.iotkit.model.biz.BizWorkorderFailure;
import cc.iotkit.model.biz.BizWorkorderMaintenance;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZoneId;
import java.util.Collection;
import java.util.List;

import static cc.iotkit.data.model.QTbBizWorkorder.tbBizWorkorder;
import static cc.iotkit.data.model.QTbBizWorkorderFailure.tbBizWorkorderFailure;
import static cc.iotkit.data.model.QTbBizWorkorderMaintenance.tbBizWorkorderMaintenance;
import static cc.iotkit.data.model.QTbBizWorkorderReplace.tbBizWorkorderReplace;
import static cc.iotkit.data.model.QTbDeviceInfo.tbDeviceInfo;
import static cc.iotkit.data.model.QTbProduct.tbProduct;
import static cc.iotkit.data.model.QTbProductModel.tbProductModel;
import static cc.iotkit.data.model.QTbSysTenant.tbSysTenant;
import static cc.iotkit.data.model.QTbSysUser.tbSysUser;

@Primary
@Service
public class BizWorkorderFailureDataImpl implements IBizWorkorderFailure, IJPACommData<BizWorkorderFailure, Long> {
    @Autowired
    private JPAQueryFactory jpaQueryFactory;
    @Autowired
    private BizWorkorderFailureRepository repository;

    @Override
    public JpaRepository getBaseRepository() {
        return repository;
    }

    @Override
    public Class getJpaRepositoryClass() {
        return TbBizWorkorderFailure.class;
    }

    @Override
    public Class getTClass() {
        return BizWorkorderFailure.class;
    }

    @Override
    public BizWorkorderFailure findByPid(Long s) {
        return MapstructUtils.convert(repository.findTbBizWorkorderFailureByPid(s), BizWorkorderFailure.class);
    }

    @Override
    public BizWorkorderFailure findById(Long s) {
        return MapstructUtils.convert(repository.findById(s).orElse(null), BizWorkorderFailure.class);
    }

    public void deleteByPid(Collection<Long> pid){
        jpaQueryFactory.delete(tbBizWorkorderFailure).where(tbBizWorkorderFailure.pid.in(pid)).execute();
    }

    @Override
    public BizWorkorderFailure save(BizWorkorderFailure data) {
        if (data.getId()==null||data.getId().equals(0L)) {
            data.setTenantId(Long.parseLong(LoginHelper.getTenantId()));
            data.setCreateDept(LoginHelper.getDeptId());
            data.setUid(LoginHelper.getUserId());
            data.setCreateAt(System.currentTimeMillis());
            data.setCreateBy(LoginHelper.getUserId());
            data.setCreateUser(LoginHelper.getUsername());
        }else{
            data.setUpdateAt(System.currentTimeMillis());
            data.setUpdateBy(LoginHelper.getUserId());
            data.setCreateUser(LoginHelper.getUsername());
        }
        repository.save(MapstructUtils.convert(data, TbBizWorkorderFailure.class));
        return data;
    }

    @Transactional
    public List<BizWorkorderFailure> saveAll(List<BizWorkorderFailure> datas) {
        for(BizWorkorderFailure data : datas){
            if (data.getId()==null||data.getId().equals(0L)) {
                data.setTenantId(Long.parseLong(LoginHelper.getTenantId()));
                data.setCreateDept(LoginHelper.getDeptId());
                data.setUid(LoginHelper.getUserId());
                data.setCreateAt(System.currentTimeMillis());
                data.setCreateBy(LoginHelper.getUserId());
                data.setCreateUser(LoginHelper.getUsername());
            }else{
                data.setUpdateAt(System.currentTimeMillis());
                data.setUpdateBy(LoginHelper.getUserId());
                data.setCreateUser(LoginHelper.getUsername());
            }
        }

        List<TbBizWorkorderFailure> results= repository.saveAll(MapstructUtils.convert(datas, TbBizWorkorderFailure.class));
        return MapstructUtils.convert(results, BizWorkorderFailure.class);
    }

    @Override
    public List<BizWorkorderFailure> findAll() {
        return MapstructUtils.convert(repository.findAll(), BizWorkorderFailure.class);
    }
    private Predicate buildPredicate(BizWorkorderFailure data) {
        return PredicateBuilder.instance()
                .and(data.getId()!=null,()->tbBizWorkorderFailure.id.eq(data.getId()))
                .and(data.getPid()!=null,()->tbBizWorkorderFailure.pid.eq(data.getPid()))
                .and(data.getBeginTime()!=null, () -> tbBizWorkorder.createAt.goe(data.getBeginTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()))
                .and(data.getEndTime()!=null, () -> tbBizWorkorder.createAt.loe(data.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()))

                /*.and(data.getDevicePartsId()!=null, () -> tbBizWorkorderFailure.devicePartsId.eq(data.getDevicePartsId()))
                .and(StringUtils.isNotEmpty(data.getDeviceId()), () -> tbBizWorkorderFailure.deviceId.eq(data.getDeviceId()))*/
                .build();
    }
    public List<BizWorkorderFailure> findAllByCondition(BizWorkorderFailure query) {
        Predicate predicate = buildPredicate(query);
        QTbSysUser customerSysUser=new QTbSysUser("customerSysUser");
        QTbSysUser workorderSysUser=new QTbSysUser("workorderSysUser");
        //关联多个相同表需要定义不同的别名
        QTbSysDictData tbSysDictDataType=new QTbSysDictData("tbSysDictDataType");
        QTbSysDictData tbSysDictDataStatus=new  QTbSysDictData("tbSysDictDataStatus");
        List<BizWorkorderFailure> results = jpaQueryFactory.select(Projections.bean(BizWorkorderFailure.class,
                        tbBizWorkorderFailure.id,tbBizWorkorder.docNumber,tbBizWorkorder.uid,tbBizWorkorder.createDept,tbBizWorkorder.tenantId,tbBizWorkorder.remark,tbBizWorkorder.createAt,tbBizWorkorder.createBy,
                        tbBizWorkorder.updateAt,tbBizWorkorder.updateBy,tbBizWorkorder.createUser,tbBizWorkorder.updateUser,
                        tbBizWorkorder.type,tbBizWorkorder.status,tbBizWorkorder.personId,tbBizWorkorder.result,tbBizWorkorder.productId,tbBizWorkorder.deviceId,
                        tbBizWorkorderFailure.failureDate,tbBizWorkorderFailure.affect,
                        Expressions.as(customerSysUser.nickName, Expressions.stringPath("creator")),
                        Expressions.as(customerSysUser.phonenumber, Expressions.stringPath("creatorPhone")),
                        Expressions.as(tbSysDictDataType.dictLabel, Expressions.stringPath("typeName")),
                        Expressions.as(tbSysDictDataStatus.dictLabel, Expressions.stringPath("statusName")),
                        Expressions.as(tbProduct.name, Expressions.stringPath("productName")),tbProduct.productKey,
                        tbDeviceInfo.deviceName,tbDeviceInfo.robotSn,tbDeviceInfo.modelId,
                        Expressions.as(tbProductModel.model, Expressions.stringPath("modelName")),
                        Expressions.as(workorderSysUser.nickName, Expressions.stringPath("personName")),
                        Expressions.as(tbSysTenant.companyName, Expressions.stringPath("tenantName"))

                ))
                .from(tbBizWorkorderFailure)
                .leftJoin(tbBizWorkorder).on(tbBizWorkorderFailure.pid.eq(tbBizWorkorder.id))
                .leftJoin(tbSysTenant).on(tbSysTenant.id.eq(tbBizWorkorder.tenantId))
                .leftJoin(tbSysDictDataType).on(tbSysDictDataType.dictType.eq("biz_workorder_type").and(tbSysDictDataType.dictValue.eq(tbBizWorkorder.type)))
                .leftJoin(tbProduct).on(tbProduct.id.eq(tbBizWorkorder.productId))
                .leftJoin(tbDeviceInfo).on(tbDeviceInfo.id.eq(tbBizWorkorder.deviceId))
                .leftJoin(tbProductModel).on(tbDeviceInfo.modelId.eq(tbProductModel.id))
                .leftJoin(workorderSysUser).on(workorderSysUser.id.eq(tbBizWorkorder.personId))
                .leftJoin(customerSysUser).on(customerSysUser.id.eq(tbBizWorkorder.createBy))
                .leftJoin(tbSysDictDataStatus).on(tbSysDictDataStatus.dictType.eq("biz_workorder_status").and(tbSysDictDataStatus.dictValue.eq(tbBizWorkorder.status)))
                .where(predicate).fetch();
        return results;

    }
    public Paging<BizWorkorderFailure> findAllByConditions(PageRequest<BizWorkorderFailure> pageRequest) {
        BizWorkorderFailure data = pageRequest.getData();
        Predicate predicate = buildPredicate(data);
        QueryResults<BizWorkorderFailure> results = jpaQueryFactory.select(Projections.bean(BizWorkorderFailure.class,
                        tbBizWorkorderFailure.id))
                .from(tbBizWorkorderFailure)
                .where(predicate).limit(pageRequest.getPageSize()).offset(pageRequest.getOffset()).fetchResults();
        return new Paging<>(results.getTotal(), results.getResults());

    }
}
